import {
	BASE_URL
} from "../config/config.js"

import {
	showConfirmDialog
} from "../hooks/useConfirm.js"

const DEFAULT_TIME_OUT = 60 * 1000;

class RequestError extends Error {
	constructor(message = "没有错误信息") {
		super(message);
		this.type = "接口错误";
	}
}

class ServerError extends Error {
	constructor(message = "请稍候重试，或联系开发者") {
		super(message);
		this.type = "服务器繁忙";
	}
}

class NetworkError extends Error {
	constructor(message = "请检查网络，或联系开发者") {
		super(message);
		this.type = "网络错误";
	}
}

/**
 * 创建HTTP请求
 * @param {Object} [globConfig] - 请求配置
 * @param {string} [globConfig.requestInterceptor] - // 请求拦截器
 * @param {Function} [globConfig.responseInterceptor] - // 响应拦截器
 * @param {Function} [globConfig.errorHandler] - // 错误处理
 * @param {Object} [globConfig.header] - 请求头，默认为空对象
 * @param {number} [globConfig.timeout] - // 请求超时时间
 */
export function useRequest(globConfig) {
	// 默认请求拦截器
	const defaultRequestInterceptor = (config) => {
		console.log("请求参数：", config);
		uni.showLoading({
			title: "发送中...",
			mask: true,
		});
		return config;
	}
	// 默认响应拦截器
	const defaultResponseInterceptor = (res) => {
		uni.hideLoading();
		if (res.statusCode < 200 || res.statusCode >= 300) {
			throw new Error(res.data.message);
		}
		return res.data.data;
	}

	// 默认错误处理
	const defaultErrorHandler = async (error) => {
		uni.hideLoading();
		console.log("请求出错", error);
		showConfirmDialog({
			title: "出错了",
			content: error.message,
		});
		return Promise.reject(error.message)
	}


	/**
	 * 发送HTTP请求
	 * @param {Object} [config] - 请求配置
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH'} config.method - HTTP请求方法
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	async function request(config) {
		let {
			requestInterceptor,
			responseInterceptor,
			errorHandler,
			...cfg
		} = config

		// 设置拦截器，没有则默认
		const reqItc = requestInterceptor || globConfig?.requestInterceptor || defaultRequestInterceptor;
		const resItc = responseInterceptor || globConfig?.responseInterceptor || defaultResponseInterceptor;
		const errHdl = errorHandler || globConfig?.errorHandler || defaultErrorHandler;
		// 设置铜冠电工还是铜陵精讯地址，先从请求中获取，没有则使用globalConfig默认配置
		const baseUrl = BASE_URL;
		// 设置header，先从请求中获取，没有则使用globalConfig默认配置
		const header = config.header || globConfig?.header || {};
		// 设置超时时间
		const timeout = config.timeout || globConfig?.timeout || DEFAULT_TIME_OUT;

		const reqCfg = {
			header,
			method: cfg.method || "GET",
			url: baseUrl + cfg.url,
			data: cfg.data,
			timeout,
		}
		console.log("请求", reqCfg);

		try {
			// 请求拦截器
			cfg = reqItc(cfg);

			// 发起请求
			const res = await uni.request(reqCfg);

			// 响应拦截器
			return resItc(res)
		} catch (error) {
			console.log("try catch error", error);
			return errHdl(error)
		}
	}

	/**
	 * 发送POST请求
	 * @param {string} url - // 接口地址
	 * @param {Object} [config] - // 请求配置
	 * @param {Object} [config.params] - //  URL请求参数
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	function get(url, config = {}) {
		const {
			params,
			...cfg
		} = config
		return request({
			url,
			method: "GET",
			data: params,
			...cfg
		});
	}

	/**
	 * 发送PUT请求
	 * @param {string} url - // 接口地址
	 * @param {Object} [config] - // 请求配置
	 * @param {Object} [config.params] - //  URL请求参数
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	function put(url, config = {}) {
		const {
			params = {},
				...cfg
		} = config

		// 构建查询参数字符串
		const queryString = Object.entries(params)
			.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
			.join('&');

		// 拼接完整URL
		const fullUrl = queryString ? `${url}?${queryString}` : url;

		return request({
			url: fullUrl,
			method: "PUT",
			// data: params,
			...cfg
		});
	}

	/**
	 * 发送POST请求
	 * @param {Object} data - // 请求体json数据
	 * @param {string} url - // 接口地址
	 * @param {Object} [config] - 请求配置
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	function post(url, data, config = {}) {

		return request({
			url,
			data,
			method: "POST",
			...config
		})
	}

	/**
	 * 发送DELETE请求
	 * @param {string} url - // 接口地址
	 * @param {Object} [config] - 请求配置
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {Object} [config.params] - query参数
	 * @param {Object} [config.data] - data参数，JSON对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	function pathch(url, config = {}) {

		return request({
			url,
			method: "PATCH",
			...config
		})
	}

	/**
	 * 发送DELETE请求
	 * @param {string} url - // 接口地址
	 * @param {Object} [config] - 请求配置
	 * @param {string} [config.requestInterceptor] - // 请求拦截器
	 * @param {Function} [config.responseInterceptor] - // 响应拦截器
	 * @param {Function} [config.errorHandler] - // 错误处理
	 * @param {Object} [config.header] - 请求头，默认为空对象
	 * @param {number} [config.timeout] - // 请求超时时间
	 */
	function del(url, config = {}) {

		return request({
			url,
			method: "DELETE",
			...config
		})
	}

	return {
		get,
		post,
		put,
		pathch,
		delete: del,
	}
}